package so.sao.shop.supplier.job;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import so.sao.shop.supplier.config.Constant;
import so.sao.shop.supplier.dao.ParameterDao;
import so.sao.shop.supplier.dao.PurchaseDao;
import so.sao.shop.supplier.dao.PurchaseItemDao;
import so.sao.shop.supplier.domain.Parameter;
import so.sao.shop.supplier.pojo.vo.PurchaseItemVo;
import so.sao.shop.supplier.pojo.vo.PurchasesVo;
import so.sao.shop.supplier.service.PurchaseService;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;

/**
 *
 * @author bzh
 * @date 2017/11/30
 */
@Component
public class AutomaticCloseTransactionJob {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * redisTemplate
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private ParameterDao parameterDao;
    @Resource
    private PurchaseItemDao purchaseItemDao;
    @Resource
    private PurchaseDao purchaseDao;
    @Resource
    private PurchaseService purchaseService;

    @Scheduled(cron = "${jobs.AutomaticCloseTransactionJob.closeTransaction}")
    public void closeTransaction() {
        /**
         * 1.五天内没有产生任何退/换货记录——已完成
         *     a.查询订单状态为已收货的订单（订单状态为12），且收货时间大于5天；
         *     b.将订单状态更改为已完成(4)，更新完成时间。
         * 2.整单退货——已完成
         *     a.供应商审核通过后（订单状态为10），5天后订单状态没有发生变化，则将订单状态更改为已完成(4);
         * 3.部分退/换货
         *     a.查询订单状态为已收货(订单状态为12)；
         *     b.查询SKU订单状态为审核通过(状态为2)，且审核时间大于5天；
         *     c.将条件符合的SKU订单状态更改为退货取消(6);
         *     d.将订单状态更改为已完成(4)。
         */
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(Constant.REDIS_KEY_PREFIX + "AUTOMATIC_CLOSE_TRANSACTION", "1");
        try {
            if (null != lock && lock) {
                //获取时间段
                List<Parameter> parameters = parameterDao.selectByKey("service_time");
                String days = parameters.get(0).getParameterValue();
                List<PurchasesVo> purchasesVos = purchaseService.getOrderInfoByOrderStatus(Constant.OrderStatusConfig.ORDER_RECEIVED);
                //1.五天内没有变动——已完成
                autoComplate(purchasesVos, days);
                //2.整单退货——已完成
                autoWholeRefundComplate(days);
                //3.部分退/换货——已完成
                sectionRefundComplate(days, purchasesVos);
            }
        } catch (Exception e) {
            logger.error("系统异常", e);
        } finally {
            if (null != lock && lock) {
                redisTemplate.delete(Constant.REDIS_KEY_PREFIX + "AUTOMATIC_CLOSE_TRANSACTION");
            }
        }
    }

    /**
     * 1.五天内没有退/换货——已完成
     */
    private void autoComplate(List<PurchasesVo> purchasesVos,String days) {
        List<String> orderIds = new ArrayList<>();
        purchasesVos.forEach(purchasesVo -> {
            if (null != purchasesVo.getOrderReceiveTime()) {
                Long timeDiff = System.currentTimeMillis() - purchasesVo.getOrderReceiveTime().getTime();
                Long times = timeDiff/(3600*1000);
                boolean daysDiff = times >= (Integer.valueOf(days)*24-1);
                if (daysDiff) {
                    orderIds.add(purchasesVo.getOrderId());
                }
            }
        });
        //判断SKU订单状态是否为终态
        if (orderIds.size()>0) {
            List<PurchaseItemVo> purchaseItemVoList = purchaseItemDao.getOrderDetailByOIds(orderIds, null, null);
            orderIds.clear();
            purchaseItemVoList.forEach(purchaseItemVo -> {
                if (Objects.equals(purchaseItemVo.getStatus(),Constant.OrderDetailsStatusConfig.COMPLATE) ||
                        Objects.equals(purchaseItemVo.getStatus(),Constant.OrderDetailsStatusConfig.REJECT) ||
                        Objects.equals(purchaseItemVo.getStatus(),Constant.OrderDetailsStatusConfig.REFUNDED) ||
                        Objects.equals(purchaseItemVo.getStatus(),Constant.OrderDetailsStatusConfig.CANCEL_ORDER)) {
                    orderIds.add(purchaseItemVo.getOrderId());
                }
            });
            if (orderIds.size()>0) {
                purchaseDao.updateRefundOrderStatus(orderIds, Constant.OrderStatusConfig.RECEIVED,new Date());
            }
        }
    }

    /**
     * 2.整单退货——已完成
     * @param days 时间段
     */
    private void autoWholeRefundComplate(String days) {
        List<PurchasesVo> purchasesVos = purchaseService.getOrderInfoByOrderStatus(Constant.OrderStatusConfig.EXAMINATION_PASSED);
        List<String> orderIds = new ArrayList<>();
        purchasesVos.forEach(purchasesVo -> {
            if (null != purchasesVo.getCheckTime()) {
                Long timeDiff = System.currentTimeMillis() - purchasesVo.getCheckTime().getTime();
                Long times = timeDiff/(3600*1000);
                boolean daysDiff = times >= (Integer.valueOf(days)*24-1);
                if (daysDiff) {
                    orderIds.add(purchasesVo.getOrderId());
                }
            }
        });
        if (orderIds.size()>0) {
            purchaseDao.updateRefundOrderStatus(orderIds, Constant.OrderStatusConfig.RECEIVED,new Date());
        }
    }

    /**
     * 3.部分退/换货——已完成
     * @param days 时间段
     * @param purchasesVos 订单列表
     */
    private void sectionRefundComplate(String days, List<PurchasesVo> purchasesVos) {
        List<String> orderIds = new ArrayList<>();
        purchasesVos.forEach(purchasesVo -> {
            orderIds.add(purchasesVo.getOrderId());
        });
        if (orderIds.size()>0) {
            List<PurchaseItemVo> purchaseItemVoList = purchaseItemDao.getOrderDetailByOIds(orderIds, null, null);
            Set<String> orderIdsSet = new HashSet<>();
            List<BigInteger> detailIds = new ArrayList<>();
            purchaseItemVoList.forEach(purchaseItemVo -> {
                if (null != purchaseItemVo.getCheckTime() &&
                        Objects.equals(purchaseItemVo.getStatus(),Constant.OrderDetailsStatusConfig.PASSED)) {
                    Long timeDiff = System.currentTimeMillis() - purchaseItemVo.getCheckTime().getTime();
                    Long times = timeDiff/(3600*1000);
                    boolean daysDiff = times >= (Integer.valueOf(days)*24-1);
                    if (daysDiff) {
                        orderIdsSet.add(purchaseItemVo.getOrderId());
                        detailIds.add(purchaseItemVo.getDetailsId());
                    }
                }
            });
            purchaseService.updateRefundOrderStatus(purchasesVos,purchaseItemVoList);
            if (detailIds.size()>0) {
                purchaseItemDao.updateOrderItemStatus(detailIds,Constant.OrderDetailsStatusConfig.CANCEL_ORDER);
            }
        }
    }
}
